package com.kylin.system.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.kylin.common.core.beans.ResultBean;
import com.kylin.common.core.constant.Constants;
import com.kylin.common.core.entity.Page;
import com.kylin.common.core.exception.CheckException;
import com.kylin.common.core.exception.ServiceException;
import com.kylin.common.core.validator.Assert;
import com.kylin.common.core.validator.BeanValidator;
import com.kylin.common.log.annotation.Log;
import com.kylin.common.log.enums.BusinessType;
import com.kylin.common.security.domain.LoginUser;
import com.kylin.common.security.util.SecurityUtils;
import com.kylin.system.entity.SysMenu;
import com.kylin.system.service.SysMenuService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单信息
 * 
 * @author wuhao
 */
@RestController
@RequestMapping("/menu")
public class SysMenuController
{
    @Autowired
    private SysMenuService menuService;

    /**
     * 获取菜单列表
     */
//    @PreAuthorize("@ss.hasPermi('system:menu:list')")
    @GetMapping("/list")
    public ResultBean<Page<SysMenu>> list(SysMenu menu)
    {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
        List<SysMenu> menus = menuService.getChildPerms(menuList, 0);

        Page<SysMenu> page = new Page<>();
        page.setRecords(menus);
        page.setSize(100);
        page.setTotal(menus.size());
        return ResultBean.onSuccess(page);
    }


    /**
     * 获取所有的页面列表
     * 方便高亮显示时候使用
     * @author wuhao
     * @version 1.0.0 - 2024/11/16
     */
    @GetMapping("/pages")
    public ResultBean<List<String>> allPages()
    {
        Long userId = SecurityUtils.getUserId();
        SysMenu menu = new SysMenu();
        menu.setHideInMenu(false);
        List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
        // 获取menuType = 1的路由名称
        List<String> pages = menuList.stream().filter(menu1 -> com.kylin.system.common.utils.Constants.TYPE_MENU.equals(menu1.getMenuType())).map(SysMenu::getRouteName).collect(Collectors.toList());
        return ResultBean.onSuccess(pages);
    }

    /**
     * 根据菜单编号获取详细信息
     */
//    @PreAuthorize("@ss.hasPermi('system:menu:query')")
    @GetMapping(value = "/{menuId}")
    public ResultBean<SysMenu> getInfo(@PathVariable Long menuId)
    {
        Assert.isBlank("查询编号不能为空", menuId);
        return ResultBean.onSuccess(menuService.getById(menuId));
    }

    /**
     * 新增菜单
     */
//    @PreAuthorize("@ss.hasPermi('system:menu:add')")
    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
    @PostMapping
    public ResultBean<Object> add(@RequestBody SysMenu menu)
    {
        // 参数校验
        BeanValidator.validate(menu);
        if("0".equals(menu.getIsFrame())
                && !StringUtils.startsWithAny(menu.getRoutePath(), Constants.HTTP, Constants.HTTPS))
        {
            throw new CheckException("新增菜单'" + menu.getMenuName() + "'失败，地址必须以http(s)://开头");
        }
        // 重名校验
        menuService.checkMenuNameUnique(menu);
        menuService.save(menu);
        return ResultBean.onSuccess();
    }

    /**
     * 修改菜单
     */
//    @PreAuthorize("@ss.hasPermi('system:menu:edit')")
    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public ResultBean<Object> edit(@RequestBody SysMenu menu)
    {
        BeanValidator.validate(menu);
        if ("0".equals(menu.getIsFrame())
                && !StringUtils.startsWithAny(menu.getRoutePath(), Constants.HTTP, Constants.HTTPS))
        {
            throw new CheckException("新增菜单'" + menu.getMenuName() + "'失败，地址必须以http(s)://开头");
        }
        // 重名校验
        menuService.checkMenuNameUnique(menu);

        // 判断是否有按钮权限

        menuService.save(menu);

        return ResultBean.onSuccess();
    }

    /**
     * 删除菜单
     */
//    @PreAuthorize("@ss.hasPermi('system:menu:remove')")
    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{menuId}")
    public ResultBean<Object> remove(@PathVariable("menuId") Long menuId)
    {
        Assert.isBlank("请选择需要删除的数据", menuId);
        if (!menuService.listChildren(menuId).isEmpty())
        {
            throw new CheckException("存在子菜单,不允许删除");
        }

        if (menuService.checkMenuExistRole(menuId))
        {
            throw new ServiceException("菜单已分配,不允许删除");
        }
        int count = menuService.delete(menuId);
        return ResultBean.onSuccess().put("count", count);
    }

    /**
     * 获取菜单下拉树列表
     */
    @GetMapping("/treeselect")
    public ResultBean<List<SysMenu>> treeselect(SysMenu menu)
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        List<SysMenu> menus = menuService.selectMenuList(menu, userId);
        return ResultBean.onSuccess(menuService.convertChildList(menus, 0L));
    }

    /**
     * 加载对应角色菜单列表树
     */
    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
    public ResultBean<Object> roleMenuTreeselect(@PathVariable("roleId") Long roleId)
    {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuList(userId);

        Map<String, Object> data = new HashMap<>(2);
        data.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
        data.put("menus", menus);
        return ResultBean.onSuccess(data);
    }

    /**
     * 获取路由信息
     * 
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public ResultBean<Object> getRouters(String type)
    {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        if("react".equals(type)) {
            return ResultBean.onSuccess(menuService.buildMenusForReact(menus));
        }

        Map<String, Object> data = new HashMap<>();
        data.put("home", "home");
        data.put("routes", menuService.buildMenus(menus));
        return ResultBean.onSuccess(data);
    }


}